import dayjs from "dayjs";

/**
 * 是否没有值
 *
 * @param v 要检查的值
 * @returns 布尔值，表示是否没有值
 */
export function isUndef(v: any): boolean {
    return v === undefined || v === null;
}

/**
 * 是否有值
 *
 * @param v 要检查的值
 * @returns 布尔值，表示是否有值
 */
export function isDef(v: any): boolean {
    return v !== undefined && v !== null;
}

export function warn(str: string): void {
    console.warn(str);
}

export function noop(): void {}

export function debounce<T extends (...args: any[]) => void>(
    fn: T,
    interval: number = 500,
    immediate: boolean = false
): (...args: Parameters<T>) => void {
    let timeout: number | null = null;

    return function (...args: Parameters<T>) {
        const context = this;
        const later = function () {
            timeout = null;
            if (!immediate) fn.apply(context, args);
        };

        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, interval);
        if (callNow) fn.apply(context, args);
    };
}

export function throttle<T extends (...args: any[]) => void>(
    fn: T,
    interval: number = 100
): (...args: Parameters<T>) => void {
    let timer: number | null = null;
    let firstTime = true;

    return function (...args: Parameters<T>) {
        const _me = this;
        if (firstTime) {
            fn.apply(_me, args);
            firstTime = false;
            return;
        }
        if (timer) return false;
        timer = setTimeout(function () {
            clearTimeout(timer);
            timer = null;
            fn.apply(_me, args);
        }, interval);
    };
}

interface BlockItem {
    id: string;
    start: string;
    end: string;
    movedStatus?: string;
}

interface Row {
    id: string;
    gtArray: BlockItem[];
}

interface Conflict {
    conflictType: string;
    conflictDesc: string;
    isIgnore: boolean;
}

export function checkConflict(
    blockItem: BlockItem,
    row: Row,
    targetBlockItem?: BlockItem
): {
    blockItem: BlockItem;
    targetRowId: string;
    blockId: string;
    adjustType: string;
    conflictList: Conflict[];
} {
    function convertTimeStr(time: string): string {
        return dayjs(time).format("MM-DD HH:mm");
    }

    const currentBlock = blockItem;
    const blockList = row.gtArray.filter((item) => {
        return (
            item.movedStatus !== "before" &&
            (targetBlockItem ? item.id !== targetBlockItem.id : true)
        );
    });

    const conflictList: Conflict[] = [];

    const blockStart = dayjs(currentBlock.start).valueOf();
    const blockEnd = dayjs(currentBlock.end).valueOf();
    for (let i = 0; i < blockList.length; i++) {
        const compareBlock = blockList[i];
        const compareBlockStart = dayjs(compareBlock.start).valueOf();
        const compareBlockEnd = dayjs(compareBlock.end).valueOf();
        if (
            (compareBlockStart < blockStart && blockStart < compareBlockEnd) ||
            (compareBlockStart < blockEnd && blockEnd < compareBlockEnd) ||
            (compareBlockStart >= blockStart && blockEnd >= compareBlockEnd)
        ) {
            const timeConflictStr = `${currentBlock.id}:(${convertTimeStr(
                currentBlock.start
            )}-${convertTimeStr(currentBlock.end)})与目标：${
                compareBlock.id
            }(${convertTimeStr(compareBlock.start)}-${convertTimeStr(
                compareBlock.end
            )})时间冲突`;

            conflictList.push({
                conflictType: "时间校验冲突",
                conflictDesc: timeConflictStr,
                isIgnore: false,
            });
        }
    }

    return {
        blockItem: blockItem,
        targetRowId: row.id,
        blockId: blockItem.id,
        adjustType: "移动",
        conflictList: conflictList,
    };
}
